package com.tianchi.lexiang.view;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.tianchi.lexiang.R;
import com.tianchi.lexiang.bean.DrawPoint;
import com.tianchi.lexiang.bean.LeXiangConstants;
import com.tianchi.lexiang.myinterface.OnHanziFinishListener;
/**
 * handwrite view
 * @author fly
 */
public class PaintView extends View{

	private static final String TAG = "PaintView";
	
//    private static final float MINP = 0.25f;
//    private static final float MAXP = 0.75f;
    
    private Bitmap  mBitmap;
    private Bitmap  mHandWritebg;
    private Canvas  mCanvas;
    private Path    mPath;
    private Paint   mBitmapPaint;
    private Paint   mPaint;
    
    private OnHanziFinishListener mListener;
    
    private int whickDraw = -1;//record whichdraw 
//    private List<DrawPoint> oneDraw = new ArrayList<DrawPoint>();
    private List<DrawPoint> wholeDraw = new ArrayList<DrawPoint>();
    
    private HandlerThread timeoutThread = new HandlerThread("paintView");
    private Handler timerOutHandler;
    private Handler mHandler = new Handler(){
    	public void handleMessage(android.os.Message msg) {
    		invalidate();
    	};
    };
    private TimeoutCheck timeoutRunnable = new TimeoutCheck();
    
    public PaintView(Context c, AttributeSet attrs) {
        super(c, attrs);
        TypedArray a = c.obtainStyledAttributes(attrs,R.styleable.MyHandwriteView);
        float scaleWidth = a.getDimension(R.styleable.MyHandwriteView_scaleWidth, 151);
        float scaleHeight = a.getDimension(R.styleable.MyHandwriteView_scaleHeight, 106);
        a.recycle();
        
        log("scaleWidth ==>"+scaleWidth+";;scaleHeight==>"+scaleHeight);
        mBitmap = Bitmap.createBitmap((int)scaleWidth,(int)scaleHeight, Bitmap.Config.ARGB_8888);
        Bitmap mHandWriteTemp=null;
        Log.d(TAG, "mBitmap.getHeight()====>"+mBitmap.getHeight());
        mHandWriteTemp = BitmapFactory.decodeStream(c.getResources().openRawResource(R.drawable.handerwrite_box));
        //calc scale width 
        float scaleWidthRate = scaleWidth /((float)mHandWriteTemp.getWidth());
        float scaleHeightRate = scaleHeight / ((float)mHandWriteTemp.getHeight());
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidthRate, scaleHeightRate);
        mHandWritebg = Bitmap.createBitmap(mHandWriteTemp, 0, 0, mHandWriteTemp.getWidth(), mHandWriteTemp.getHeight(), matrix,true);
        mCanvas = new Canvas(mBitmap);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        mCanvas.drawBitmap(mHandWritebg, 0, 0, mBitmapPaint);
        initPaint();
        timeoutThread.start();
        timerOutHandler = new Handler(timeoutThread.getLooper());
    }

    
    public void setHanziFinishListener(OnHanziFinishListener mListener){
    	this.mListener = mListener;
    }
    
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(0xFFAAAAAA);
        
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        
        canvas.drawPath(mPath, mPaint);
    }
    
    private void initPaint(){
    	mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(0xFFFF0000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(6);
        mPaint.setColor(Color.BLUE);
    }
    
    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;
    
    private void touch_start(float x, float y) {
    	timerOutHandler.removeCallbacks(timeoutRunnable);
    	
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }
    
    private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
            mX = x;
            mY = y;
        }
    }
    
    private void touch_up() {
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        mPath.reset();
        
        timerOutHandler.postDelayed(timeoutRunnable, 2000);
    }
    
    private void actionDownTurnToDrawPoint(float x, float y){
    	Log.d(TAG, "actionDownTurnToDrawPoint x==>"+x+";;y==>"+y);
    	DrawPoint mPoint = DrawPoint.getDrawPoint();
    	mPoint.whichDraw = ++whickDraw;
    	mPoint.x = (int)x;
    	mPoint.y = (int)y;
//    	oneDraw.add(mPoint);
    	wholeDraw.add(mPoint);
    }
    
    private void actionMoveTurnToDrawPoint(float x, float y){
    	Log.d(TAG, "actionMoveTurnToDrawPoint x==>"+x+";;y==>"+y);
    	DrawPoint mPoint = DrawPoint.getDrawPoint();
    	mPoint.whichDraw = whickDraw;
    	mPoint.x = (int)x;
    	mPoint.y = (int)y;
//    	oneDraw.add(mPoint);
    	wholeDraw.add(mPoint);
    }
    
    private void actionUpTurnToDrawPoint(float x, float y){
    	Log.d(TAG, "actionUpTurnToDrawPoint x==>"+x+";;y==>"+y);
    	DrawPoint mPoint = DrawPoint.getDrawPoint();
    	mPoint.whichDraw = whickDraw;
    	mPoint.x = (int)x;
    	mPoint.y = (int)y;
//    	oneDraw.add(mPoint);
    	wholeDraw.add(mPoint);
//    	mListener.onOneDrawFinish(oneDraw);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                actionDownTurnToDrawPoint(x,y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                actionMoveTurnToDrawPoint(x,y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touch_up();
                actionUpTurnToDrawPoint(x,y);
                invalidate();
                break;
        }
        return true;
    }
    
    class TimeoutCheck implements Runnable{
		@Override
		public void run() {
			whickDraw = -1;
			DrawPoint.resetCacheDrawPointUseingState();
			mListener.onOneHanziFinish(wholeDraw);
			Log.d(TAG, "after finger up 2s,clear screen");
			mCanvas.drawColor(0xFFAAAAAA);
			mCanvas.drawBitmap(mHandWritebg, 0, 0, mBitmapPaint);
			mHandler.sendEmptyMessage(0);
		}
    }
    
    private void log(String msg){
    	Log.d(LeXiangConstants.TAG, "["+TAG+"]"+msg);
    }
}
